Like I've said, Perl5 lvalue subs by themselves are not useful for Design by Contract-style data validation preconditions and postconditions, as you cannot examine the data on input or output (but check out the comments on that post). No such limitation exists with Perl6 rw subs and Visual Basic Properties, so let's see some examples of data validation preconditions and postconditions.
This Perl6 example should work in the current Pugs (tested on the Win32 Pugs of June 6, 2006, 04:35 EST). A variable that can only have the values of:
can be implemented in Perl6 today with an rw sub as:
my $url_value = ""; sub specific_url is rw { if ($url_value ne "http://example.com/stories") { $url_value = ""; } else { $url_value = "http://example.com/stories"; } return $url_value; }
The sequence:
specific_url() = "http://example.com/stories"; say "specific_url = ", specific_url(), "\n"; specific_url() = "http://example.com/news"; say "specific_url = ", specific_url(), "\n";
yields this output:
specific_url = http://example.com/stories specific_url =
As specified above, specific_url() can only be assigned a value of "http://example.com/stories". Any other attempt at assignment causes specific_url() to take on a value of "".
Although VB Properties were originally designed for exposing the adjustable parameters of Windows controls (comboboxes, timers, etc.), they also provide a dandy way to give your VB variables their preconditions and postconditions. A VB class property for U.S. Social Security numbers would look like this (along with a 'notSS' property for comparison purposes):
Public Property Let SocialSecurity(newSocialSecurity As String) If Not newSocialSecurity Like "###-##-####" Then mSocialSecurity = "" Else mSocialSecurity = newSocialSecurity End If End Property Public Property Get SocialSecurity() As String SocialSecurity = mSocialSecurity End Property Public Property Let notSS(newNotSS As String) mNotSS = newNotSS End Property Public Property Get notSS() As String notSS = mNotSS End Property
SocialSecurity can only be assigned a validly-formatted U.S. Social Security number, yet code that uses the SocialSecurity Property looks just like code that uses a VB String for a Social Security number:
ss1.notSS = "300-42-980A" ss1.SocialSecurity = "300-42-980A" ss2.SocialSecurity = "300-42-9805" Debug.Print "notSS = '" & ss1.notSS & "'" Debug.Print "ss1 = '" & ss1.SocialSecurity & "'" Debug.Print "ss2 = '" & ss2.SocialSecurity & "'"
yields this output:
notSS = '300-42-980A' ss1 = '' ss2 = '300-42-9805'
As you can see, the SocialSecurity property only accepts a validly-formatted U.S. Social Security number, but the plain String-valued Property accepts any old String value.
There's much more to Design by Contract than preconditions and postconditions, of course, but this brief essay should give you a leg up on this important technique for easing the pain of data validation.